package com.jotta.client;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Gallery;
import android.widget.Gallery.LayoutParams;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher;

import com.jotta.client.communicate.Configuration;
import com.jotta.client.communicate.ModeOfSeverCommunicate;
import com.jotta.client.communicate.ServerCommunicator;
import com.jotta.client.communicate.StateOfClient;
import com.jotta.client.data.FileInfo;
import com.jotta.client.data.ImageAdapter;
import com.jotta.client.data.ItemInfo;
import com.jotta.client.data.PictureInfo;
import com.jotta.client.dataaccess.DataAccess;
import com.jotta.client.exception.NetworkException;
import com.jotta.client.exception.ServerException;
import com.jotta.client.setting.SettingManager;
import com.jotta.client.utility.Utility;

public class ImageBrowser extends Activity implements ViewSwitcher.ViewFactory,
        Runnable, OnItemClickListener {

    private ImageSwitcher mSwitcher;
    private ProgressDialog m_ProgressDialog;
    private ArrayList<PictureInfo> pictureInfos;
    private Gallery gallery;
    private String username, password, swipePath, latestFileView;
    private PictureInfo selectedItem;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_view);

        Configuration.prepareConfiguration(this);
        DataAccess.getInstance().initializeDatabase(this);

        Bundle extras = getIntent().getExtras();

        if (extras != null) {
            swipePath = extras.getString(Configuration.SWIPE_PATH);
            latestFileView = extras.getString(Configuration.FILE_NAME);

            if (swipePath == "")
                swipePath = SettingManager.getInstance().getLatestSwipePath(
                        getPreferences(MODE_PRIVATE));

            if (latestFileView == "")
                latestFileView = SettingManager.getInstance()
                        .getLatestFileView(getPreferences(MODE_PRIVATE));

        }

        username = SettingManager.getInstance().getUsername();
        password = SettingManager.getInstance().getPassword();

        mSwitcher = (ImageSwitcher) findViewById(R.id.switcher);
        mSwitcher.setFactory(this);
        mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
                android.R.anim.fade_in));
        mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
                android.R.anim.fade_out));

        gallery = (Gallery) findViewById(R.id.gallery);
        gallery.setOnItemClickListener(this);
        startThreadGetPictureInfos();
    }

    /*
      * (non-Javadoc)
      *
      * @see android.app.Activity#onStop()
      */
    @Override
    protected void onStop() {


        SettingManager.getInstance().setLatestSwipePath(
                getPreferences(MODE_PRIVATE), swipePath);

        SettingManager.getInstance().setLatestFileView(
                getPreferences(MODE_PRIVATE), latestFileView);

        super.onStop();
    }

    /*
      * (non-Javadoc)
      *
      * @see android.app.Activity#onStop()
      */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        finish();
    }

    public void onItemClick(AdapterView<?> arg0, View arg1, int position,long id) {
        try {
            selectedItem = pictureInfos.get(position);
            if (selectedItem.isDownloaded()) {
                setSelectedImagePicture();
            } else {
                if (selectedItem.getFileSize() > SettingManager.getInstance().getLocalFreeSpace()) {
                    showNotEnoughFreeSpaceDialog(selectedItem);
                } else {
                    Configuration.setModeOfSeverCommunicate(ModeOfSeverCommunicate.DOWNLOAD);
                    startThread2DownloadFile();
                }
            }
        } catch (Exception e) {
            Utility.getAlertDialog(ImageBrowser.this, Configuration.getRes(), e.getMessage());
        }
    }

    /**
     * Start new thread to login when activity is restart
     */
    private void startThreadGetPictureInfos() {
        Configuration.setModeOfSeverCommunicate(ModeOfSeverCommunicate.GET_SERVER_INFOMATION);
        Thread thread = new Thread(this);
        thread.start();
        // initialize progress bar
        m_ProgressDialog = Utility.getProgressBar(ImageBrowser.this, Configuration.getRes());
        m_ProgressDialog.show();
    }

    /*
      * Get data from server & notified to handler when finished
      *
      * @see java.lang.Runnable#run()
      */
    public void run() {
        if (Configuration.getModeOfSeverCommunicate() == ModeOfSeverCommunicate.GET_SERVER_INFOMATION) {
            getServerInformation();

        } else if (Configuration.getModeOfSeverCommunicate() == ModeOfSeverCommunicate.DOWNLOAD) {
            downloadFileFromSever();

        } else if (Configuration.getModeOfSeverCommunicate() == ModeOfSeverCommunicate.DOWNLOAD_WITH_AUTO_DELETE) {

            FileInfo fileInfo = selectedItem;
            Configuration.setStateOfClient(StateOfClient.AUTO_DELETE_SERVICE);

            if (DataAccess.getInstance().autoDeleteService(fileInfo.getFileSize())) {
                downloadFileFromSever();
            } else {
                autoDeleteNotSuccessHandler.sendEmptyMessage(0);
                Configuration.setStateOfClient(StateOfClient.OFFLINE);
            }
        }
    }

    private void downloadFileFromSever() {
        Configuration.setStateOfClient(StateOfClient.DOWNLOADING);
        Bundle bundle = new Bundle();

        Message msg = new Message();
        String serverMessage = "";
        try {
            ServerCommunicator communicator = ServerCommunicator.getInstance(ImageBrowser.this.updateProgressBarHandler);

            FileInfo fileInfo = selectedItem;
            String downloadPath = fileInfo.getDownloadPathOfItem();
            String filePath = fileInfo.getServerPathOfItem();
            //String fileName = fileInfo.getTitle();
            long fileSize = fileInfo.getFileSize();

            communicator.downloadFile(downloadPath, filePath, fileSize);
            serverMessage = Configuration.GET_DATA_SUCCESSFUL_MESSAGE;

        } catch (ServerException e) {
            serverMessage = e.getErrorMessage();

        } catch (NetworkException e) {
            serverMessage = e.getErrorMessage();

        } catch (Exception e) {
            if (e.getMessage() != null) {
                serverMessage = e.getMessage();
            } else {
                serverMessage = e.toString();

            }
        }

        bundle.putString(Configuration.SERVER_MESSAGE_KEY, serverMessage);

        msg.setData(bundle);
        downloadedHandler.sendMessage(msg);
        Configuration.setStateOfClient(StateOfClient.OFFLINE);
    }

    /**
     * When auto delete service not success dismiss progress dialog, and showing
     * the aler dialog
     */
    private Handler autoDeleteNotSuccessHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            m_ProgressDialog.setProgress(100);
            m_ProgressDialog.dismiss();
            Utility.getAlertDialog(
                    ImageBrowser.this,
                    Configuration.getRes(),
                    Configuration.getRes().getString(
                            R.string.auto_service_not_sucess)).show();
        }
    };

    private void getServerInformation() {

        Configuration.setStateOfClient(StateOfClient.GETTING_SERVER_INFORMATION);
        String message = Configuration.GET_DATA_SUCCESSFUL_MESSAGE;

        if (Configuration.getModeOfSeverCommunicate() == ModeOfSeverCommunicate.GET_SERVER_INFOMATION) {
            try {
                ServerCommunicator communicator = ServerCommunicator.getInstance(updateProgressBarHandler);
                pictureInfos = communicator.getPictureInfos(username, password, swipePath);

            } catch (ServerException e) {
                message = e.getErrorMessage();
            } catch (NetworkException e) {
                message = e.getErrorMessage();
            } catch (Exception e) {
                message = e.getMessage();
            }
        }

        Bundle bundle = new Bundle();
        bundle.putString(Configuration.SERVER_MESSAGE_KEY, message);
        Message msg = new Message();
        msg.setData(bundle);

        getInformationFinishedHandler.sendMessage(msg);
        Configuration.setStateOfClient(StateOfClient.OFFLINE);

    }

    private void showNotEnoughFreeSpaceDialog(ItemInfo itemInfo) {
        String autoDelete = Configuration.getRes().getString(
                R.string.auto_delete_free_space_dialog);

        String cancel = Configuration.getRes().getString(
                R.string.cancel_free_space_dialog);
        final CharSequence[] items = {autoDelete, cancel};
        AlertDialog.Builder builder = new AlertDialog.Builder(ImageBrowser.this);
        builder.setTitle(Configuration.getRes().getString(
                R.string.not_enough_free_space_dialog_header));

        builder.setItems(items, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                if (item == 0) {
                    Configuration
                            .setModeOfSeverCommunicate(ModeOfSeverCommunicate.DOWNLOAD_WITH_AUTO_DELETE);
                    startThread2DownloadFile();
                }
            }
        });

        AlertDialog alert = builder.create();
        alert.show();
    }

    private void startThread2DownloadFile() {
        if ((Configuration.getModeOfSeverCommunicate() == ModeOfSeverCommunicate.DOWNLOAD)
                || (Configuration.getModeOfSeverCommunicate() == ModeOfSeverCommunicate.DOWNLOAD_WITH_AUTO_DELETE)) {
            Thread thread = new Thread(this);
            thread.start();

            // initialize progress bar
            m_ProgressDialog = Utility.getProgressBar(ImageBrowser.this,
                    Configuration.getRes()
            );
            m_ProgressDialog.show();
        }
    }

    public View makeView() {
        ImageView i = new ImageView(this);
        i.setBackgroundColor(0xFF000000);
        i.setScaleType(ImageView.ScaleType.FIT_CENTER);
        i.setLayoutParams(new ImageSwitcher.LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        return i;
    }

    /**
     * update progress of progress bar
     */
    private Handler updateProgressBarHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            int progress = msg.getData().getInt(
                    Configuration.PROGRESS_BAR_PERCENT);
            String downloadHeader = msg.getData().getString(
                    Configuration.DOWNLOAD_HEADER);
            if (m_ProgressDialog != null) {
                m_ProgressDialog.setProgress(progress);
                m_ProgressDialog.setMessage(downloadHeader);
            }
        }
    };

    /**
     * When load data from server finished dismiss progress dialog
     */
    private Handler getInformationFinishedHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String message = msg.getData().getString(
                    Configuration.SERVER_MESSAGE_KEY);
            if (!message.equals(Configuration.GET_DATA_SUCCESSFUL_MESSAGE)) {
                m_ProgressDialog.dismiss();
                Utility.getAlertDialog(ImageBrowser.this,
                        Configuration.getRes(), message).show();
            } else {
                gallery.setAdapter(new ImageAdapter(ImageBrowser.this,
                        pictureInfos));

                int position = Utility.getIndexOfPictureInfo(pictureInfos,
                        latestFileView);
                gallery.setSelection(position);
                selectedItem = pictureInfos.get(position);
                setSelectedImagePicture();
                m_ProgressDialog.dismiss();
            }
        }
    };

    /**
     * When download file from server finished dismiss progress dialog
     */
    private Handler downloadedHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            String message = msg.getData().getString(
                    Configuration.SERVER_MESSAGE_KEY);
            if (!message.equals(Configuration.GET_DATA_SUCCESSFUL_MESSAGE)) {
                m_ProgressDialog.dismiss();
                Utility.getAlertDialog(ImageBrowser.this,
                        Configuration.getRes(), message).show();
            } else {
                PictureInfo fileInfo = selectedItem;
                DataAccess.getInstance().recordNewFileIntoDatabase(fileInfo);

                ImageView selectedView = (ImageView) gallery.getSelectedView();
                Drawable toRecycle = selectedView.getDrawable();
                if (toRecycle != null)
                    ((BitmapDrawable) toRecycle).getBitmap().recycle();

                selectedView.setImageBitmap(selectedItem.getThumbnail());

                setSelectedImagePicture();
                m_ProgressDialog.dismiss();
            }
        }
    };

    private void setSelectedImagePicture() {
        try {
            updateCurrentTitle();
            Bitmap bitmap = mSwitcher.getDrawingCache();
            if (bitmap != null) {
                bitmap.recycle();
            }
            mSwitcher.setImageDrawable(selectedItem.getImageDrawable());

        } catch (OutOfMemoryError e) {
            Utility.getAlertDialog(
                    ImageBrowser.this,
                    Configuration.getRes(),
                    Configuration.getRes().getString(
                            R.string.out_of_memory_when_view_picture)).show();
        }
    }

    private void updateCurrentTitle() {
        String app_name = Configuration.getRes().getString(R.string.app_name);
        setTitle(app_name + " - " + selectedItem.getTitle());
    }
}
